home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Devices and Hardware / Velocity Engine / VelEng Wavelet / source / VWavelet_int.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-28  |  48.5 KB  |  1,344 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        VWavelet_int.c
  3.  
  4.     Contains:    Velocity Engine integer implementation Daubechies D4 wavelet code
  5.  
  6.     Copyright:    Copyright © 2000 by Apple Computer, Inc., All Rights Reserved.
  7.  
  8.                 You may incorporate this Apple sample source code into your program(s) without
  9.                 restriction. This Apple sample source code has been provided "AS IS" and the
  10.                 responsibility for its operation is yours. You are not permitted to redistribute
  11.                 this Apple sample source code as "Apple sample source code" after having made
  12.                 changes. If you're going to re-distribute the source, we require that you make
  13.                 it clear in the source that the code was descended from Apple sample source
  14.                 code, but that you've made changes.
  15.  
  16.                 
  17.  
  18. */
  19. /*
  20.     Disclaimer:    IMPORTANT:  This Apple software is supplied to you by Apple Computer, Inc.
  21.                 ("Apple") in consideration of your agreement to the following terms, and your
  22.                 use, installation, modification or redistribution of this Apple software
  23.                 constitutes acceptance of these terms.  If you do not agree with these terms,
  24.                 please do not use, install, modify or redistribute this Apple software.
  25.  
  26.                 In consideration of your agreement to abide by the following terms, and subject
  27.                 to these terms, Apple grants you a personal, non-exclusive license, under Apple’s
  28.                 copyrights in this original Apple software (the "Apple Software"), to use,
  29.                 reproduce, modify and redistribute the Apple Software, with or without
  30.                 modifications, in source and/or binary forms; provided that if you redistribute
  31.                 the Apple Software in its entirety and without modifications, you must retain
  32.                 this notice and the following text and disclaimers in all such redistributions of
  33.                 the Apple Software.  Neither the name, trademarks, service marks or logos of
  34.                 Apple Computer, Inc. may be used to endorse or promote products derived from the
  35.                 Apple Software without specific prior written permission from Apple.  Except as
  36.                 expressly stated in this notice, no other rights or licenses, express or implied,
  37.                 are granted by Apple herein, including but not limited to any patent rights that
  38.                 may be infringed by your derivative works or by other works in which the Apple
  39.                 Software may be incorporated.
  40.  
  41.                 The Apple Software is provided by Apple on an "AS IS" basis.  APPLE MAKES NO
  42.                 WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
  43.                 WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  44.                 PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
  45.                 COMBINATION WITH YOUR PRODUCTS.
  46.  
  47.                 IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
  48.                 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  49.                 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  50.                 ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
  51.                 OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
  52.                 (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
  53.                 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  54. */
  55.  
  56. #ifdef __MWERKS__
  57. #include <altivec.h>
  58. #endif
  59.  
  60. #include <MacTypes.h>
  61. #include <MacMemory.h>
  62.  
  63. #include "vWavelet_int.h"
  64.  
  65. typedef     signed long DATA_TYPE;
  66.  
  67. #define DO_HORIZ 1
  68. #define DO_VERT 1
  69.  
  70. #define INT_SHIFT_AMOUNT    0
  71.  
  72. #define    H0    (11 * (1<< INT_SHIFT_AMOUNT))
  73. #define    H1    (19 * (1<< INT_SHIFT_AMOUNT))
  74. #define    H2    (5 * (1<< INT_SHIFT_AMOUNT))
  75. #define    H3    (-3 * (1<< INT_SHIFT_AMOUNT))
  76.  
  77. #define INT_WAVELET_SHIFT_AMOUNT        4
  78. #define INVERSE_WAVELET_SHIFT_AMOUNT    5
  79.  
  80. #pragma mark F O R W A R D  W A V E L E T
  81.  
  82. ////////////////////////////////////////////////////////////////////////////
  83. // vFWVT_4_Quad16_Int_Vertical 
  84. // 
  85. // performs a forward vertical wavelet transform
  86. //
  87. // pSrc:                source pixels (16-bit interleaved RGBA channels)
  88. // pDest:                destination for transform data (16-bit interleaved RGBA channels)
  89. // numQuads:            vertical pixel count
  90. // skipQuadCount:        number of quads between row starts
  91. // columns:                number of columns on which to perform transform
  92. ////////////////////////////////////////////////////////////////////////////
  93. void vFWVT_4_Quad16_Int_Vertical(vector signed long *pSrc,
  94.                             vector signed long *pDest,
  95.                             unsigned long numQuads,
  96.                             unsigned long skipQuadCount,
  97.                             unsigned long    columns)                
  98. {
  99.     long                     length = (numQuads/2);
  100.     long                    vectorInIndex;
  101.     long                    skipVectors = skipQuadCount / 2;
  102.     long                    columnPairCount = columns / 2;
  103.     long                    columnPairIndex;
  104.     
  105.     vector signed short        *pSrcInput;
  106.     vector signed long        *pLoOutput;
  107.     vector signed long        *pHiOutput;
  108.     
  109.     // vectors that contain wavelet coefficients
  110.     vector signed short            vMUL0    = (vector signed short)(H0, H1, H0, H1,H0, H1,H0, H1);
  111.     vector signed short            vMUL1    = (vector signed short)(H2, H3, H2, H3,H2, H3,H2, H3);
  112.     vector signed short            vMUL2    = (vector signed short)(H3, -H2,H3, -H2,H3, -H2,H3, -H2);
  113.     vector signed short            vMUL3    = (vector signed short)(H1, -H0,H1, -H0,H1, -H0,H1, -H0);
  114.  
  115.     vector signed short            vCand1;
  116.     vector signed short            vCand2;
  117.     vector signed short            vCand3;
  118.     vector signed short            vCand4;
  119.  
  120.     vector unsigned char        vPermuter1 = (vector unsigned char)(0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13, 0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17);
  121.     vector unsigned char        vPermuter2 = (vector unsigned char)(0x08, 0x09, 0x18, 0x19, 0x0a, 0x0b, 0x1a, 0x1b, 0x0c, 0x0d, 0x1c, 0x1d, 0x0e, 0x0f, 0x1e, 0x1f);
  122.     
  123.     vector unsigned long        vecEndShift = (vector unsigned long)(INT_WAVELET_SHIFT_AMOUNT);
  124.     vector signed long            vecEndAdd = (vector signed long)(1 << (INT_WAVELET_SHIFT_AMOUNT-1));
  125.     
  126.     vector signed short            vInVector1, vInVector2, vInVector3, vInVector4;
  127.     vector signed long            vResult1, vResult2, vResult3, vResult4;
  128.     vector signed short            vInVectorFirst, vInVectorSecond;
  129.     
  130.  
  131.     for (columnPairIndex = 0; columnPairIndex < columnPairCount; columnPairIndex++) {
  132.  
  133.         pSrcInput = ((vector signed short*)pSrc) + columnPairIndex;
  134.         pLoOutput = (vector signed long*)pDest+columnPairIndex;
  135.         pHiOutput = (vector signed long*)pLoOutput + ((skipQuadCount/2) *length);
  136.  
  137.         // read the first four in, and save 1 and 2 for wraparound at end
  138.         vInVector1 = *pSrcInput;
  139.         pSrcInput += skipVectors;
  140.         vInVectorFirst = vInVector1;
  141.         
  142.         vInVector2 =     *pSrcInput;
  143.         pSrcInput += skipVectors;
  144.         vInVectorSecond = vInVector2;
  145.         
  146.         vInVector3 = *pSrcInput;
  147.         pSrcInput += skipVectors;
  148.  
  149.         vInVector4 = *pSrcInput;
  150.         pSrcInput += skipVectors;
  151.         
  152.         // set up multiplicand vectors using raw input vectors and permute instruction
  153.         vCand1 = vec_perm(vInVector1, vInVector2, vPermuter1);
  154.         vCand2 = vec_perm(vInVector3, vInVector4, vPermuter1);
  155.         vCand3 = vec_perm(vInVector1, vInVector2, vPermuter2);
  156.         vCand4 = vec_perm(vInVector3, vInVector4, vPermuter2);
  157.         
  158.         // calculate pixel results by multiplying elements by the wavelet coefficients, 
  159.         // with additional add for appropriate rounding in divide
  160.         vResult1 = vec_msum(vMUL0, vCand1, (vector signed long)vecEndAdd);
  161.         vResult1 = vec_msum(vMUL1, vCand2, vResult1);
  162.         
  163.         vResult2 = vec_msum(vMUL2, vCand1, (vector signed long)vecEndAdd);
  164.         vResult2 = vec_msum(vMUL3, vCand2, vResult2);
  165.  
  166.         vResult3 = vec_msum(vMUL0, vCand3, (vector signed long)vecEndAdd);
  167.         vResult3 = vec_msum(vMUL1, vCand4, vResult3);
  168.         
  169.         vResult4 = vec_msum(vMUL2, vCand3, (vector signed long)vecEndAdd);
  170.         vResult4 = vec_msum(vMUL3, vCand4, vResult4);
  171.  
  172.         // do end shift to perform divide
  173.         vResult1 = vec_sra(vResult1,vecEndShift);
  174.         vResult2 = vec_sra(vResult2,vecEndShift);
  175.         vResult3 = vec_sra(vResult3,vecEndShift);
  176.         vResult4 = vec_sra(vResult4,vecEndShift);
  177.         
  178.         // pack results to 16 bits
  179.         vResult1 = (vector signed long)vec_pack(vResult1, vResult3);
  180.         vResult2 = (vector signed long)vec_pack(vResult2, vResult4);
  181.         
  182.         // store results
  183.         *pLoOutput = vResult1;
  184.         pLoOutput += skipVectors;
  185.  
  186.         *pHiOutput = vResult2;
  187.         pHiOutput += skipVectors;
  188.         
  189.         vInVector1 = vInVector3;
  190.         vInVector2 = vInVector4;
  191.  
  192.         vInVector3 = *pSrcInput;
  193.         pSrcInput += skipVectors;
  194.  
  195.         vInVector4 = *pSrcInput;
  196.         pSrcInput += skipVectors;
  197.         
  198.         // loop through remaining pixels
  199.         for (vectorInIndex = 0; vectorInIndex < length-2; vectorInIndex++) {
  200.                             
  201.             // set up multiplicand vectors using raw input vectors and permute instruction
  202.             vCand1 = vec_perm(vInVector1, vInVector2, vPermuter1);
  203.             vCand2 = vec_perm(vInVector3, vInVector4, vPermuter1);
  204.             vCand3 = vec_perm(vInVector1, vInVector2, vPermuter2);
  205.             vCand4 = vec_perm(vInVector3, vInVector4, vPermuter2);
  206.             
  207.             // calculate pixel results by multiplying elements by the wavelet coefficients, 
  208.             // with additional add for appropriate rounding in divide
  209.             vResult1 = vec_msum(vMUL0, vCand1, (vector signed long)vecEndAdd);
  210.             vResult1 = vec_msum(vMUL1, vCand2, vResult1);
  211.             
  212.             vResult2 = vec_msum(vMUL2, vCand1, (vector signed long)vecEndAdd);
  213.             vResult2 = vec_msum(vMUL3, vCand2, vResult2);
  214.  
  215.             vResult3 = vec_msum(vMUL0, vCand3, (vector signed long)vecEndAdd);
  216.             vResult3 = vec_msum(vMUL1, vCand4, vResult3);
  217.             
  218.             vResult4 = vec_msum(vMUL2, vCand3, (vector signed long)vecEndAdd);
  219.             vResult4 = vec_msum(vMUL3, vCand4, vResult4);
  220.  
  221.             // do end shift to perform divide
  222.             vResult1 = vec_sra(vResult1,vecEndShift);
  223.             vResult2 = vec_sra(vResult2,vecEndShift);
  224.             vResult3 = vec_sra(vResult3,vecEndShift);
  225.             vResult4 = vec_sra(vResult4,vecEndShift);
  226.             
  227.             // pack results to 16 bits
  228.             vResult1 = (vector signed long)vec_pack(vResult1, vResult3);
  229.             vResult2 = (vector signed long)vec_pack(vResult2, vResult4);
  230.             
  231.             // store results
  232.             *pLoOutput = vResult1;
  233.             pLoOutput += skipVectors;
  234.  
  235.             *pHiOutput = vResult2;
  236.             pHiOutput += skipVectors;
  237.             
  238.             vInVector1 = vInVector3;
  239.             vInVector2 = vInVector4;
  240.             
  241.             vInVector3 = *pSrcInput;
  242.             pSrcInput += skipVectors;
  243.  
  244.             vInVector4 = *pSrcInput;
  245.             pSrcInput += skipVectors;
  246.             
  247.         }
  248.                 
  249.         // copy initial vectors for wraparound at end
  250.         vInVector3 = vInVectorFirst;
  251.         vInVector4 = vInVectorSecond;
  252.         
  253.         // set up multiplicand vectors using raw input vectors and permute instruction
  254.         vCand1 = vec_perm(vInVector1, vInVector2, vPermuter1);
  255.         vCand2 = vec_perm(vInVector3, vInVector4, vPermuter1);
  256.         vCand3 = vec_perm(vInVector1, vInVector2, vPermuter2);
  257.         vCand4 = vec_perm(vInVector3, vInVector4, vPermuter2);
  258.         
  259.         // calculate pixel results by multiplying elements by the wavelet coefficients, 
  260.         // with additional add for appropriate rounding in divide
  261.         vResult1 = vec_msum(vMUL0, vCand1, (vector signed long)vecEndAdd);
  262.         vResult1 = vec_msum(vMUL1, vCand2, vResult1);
  263.         
  264.         vResult2 = vec_msum(vMUL2, vCand1, (vector signed long)vecEndAdd);
  265.         vResult2 = vec_msum(vMUL3, vCand2, vResult2);
  266.  
  267.         vResult3 = vec_msum(vMUL0, vCand3, (vector signed long)vecEndAdd);
  268.         vResult3 = vec_msum(vMUL1, vCand4, vResult3);
  269.         
  270.         vResult4 = vec_msum(vMUL2, vCand3, (vector signed long)vecEndAdd);
  271.         vResult4 = vec_msum(vMUL3, vCand4, vResult4);
  272.  
  273.         // do end shift to perform divide
  274.         vResult1 = vec_sra(vResult1,vecEndShift);
  275.         vResult2 = vec_sra(vResult2,vecEndShift);
  276.         vResult3 = vec_sra(vResult3,vecEndShift);
  277.         vResult4 = vec_sra(vResult4,vecEndShift);
  278.         
  279.         // pack results to 16 bits
  280.         vResult1 = (vector signed long)vec_pack(vResult1, vResult3);
  281.         vResult2 = (vector signed long)vec_pack(vResult2, vResult4);
  282.         
  283.         // store results
  284.         *pLoOutput = vResult1;
  285.         *pHiOutput = vResult2;
  286.     }
  287. }
  288.  
  289.  
  290. ////////////////////////////////////////////////////////////////////////////
  291. // vFWVT_4_Quad16_Int 
  292. // 
  293. // performs a forward horizontal wavelet transform
  294. //
  295. // pSrc:                source pixels (16-bit interleaved RGBA channels)
  296. // pDest:                destination for transform data (16-bit interleaved RGBA channels)
  297. // numQuads:            horizontal pixel count
  298. // skipQuads:            number of quads between row starts
  299. // numRows:                number of rows on which to perform transform
  300. ////////////////////////////////////////////////////////////////////////////
  301. void vFWVT_4_Quad16_Int(    vector signed long *pSrc,
  302.                             vector signed long *pDest,
  303.                             unsigned long numQuads,
  304.                             unsigned long skipQuads,
  305.                             unsigned long numRows)                
  306. {
  307.     long                    vectorInIndex;
  308.     long                    rowIndex;
  309.     
  310.     vector signed short        *pSrcInput;
  311.     vector signed long        *pLoOutput;
  312.     vector signed long        *pHiOutput;
  313.  
  314.     // vectors that contain wavelet coefficients
  315.     vector signed short            vMUL0    = (vector signed short)(H0, H1, H0, H1,H0, H1,H0, H1);
  316.     vector signed short            vMUL1    = (vector signed short)(H2, H3, H2, H3,H2, H3,H2, H3);
  317.     vector signed short            vMUL2    = (vector signed short)(H3, -H2,H3, -H2,H3, -H2,H3, -H2);
  318.     vector signed short            vMUL3    = (vector signed short)(H1, -H0,H1, -H0,H1, -H0,H1, -H0);
  319.  
  320.     vector signed short            vCand1;
  321.     vector signed short            vCand2;
  322.     vector signed short            vCand3;
  323.  
  324.     vector unsigned char        vPermuter = (vector unsigned char)(0x00, 0x01, 0x08, 0x09, 0x02, 0x03, 0x0a, 0x0b, 0x04, 0x05, 0x0c, 0x0d, 0x06, 0x07, 0x0e, 0x0f);
  325.     
  326.     vector unsigned long        vecEndShift = (vector unsigned long)(INT_WAVELET_SHIFT_AMOUNT);
  327.     vector signed long            vecEndAdd = (vector signed long)(1 << (INT_WAVELET_SHIFT_AMOUNT-1));
  328.     
  329.     vector signed short            vInVector1, vInVector2, vInVector3;
  330.     vector signed long            vResult1, vResult2, vResult3, vResult4;
  331.     vector signed short            vInVectorFirst;
  332.     
  333.     for (rowIndex = 0; rowIndex < numRows; rowIndex++) {
  334.         
  335.         pSrcInput = (vector signed short*)pSrc+(rowIndex*(skipQuads/2));
  336.         pLoOutput = (vector signed long*)pDest+(rowIndex*(skipQuads/2));
  337.         pHiOutput = pLoOutput + (numQuads/4);
  338.     
  339.         // read the first four in, and save 1 for wraparound at end
  340.         vInVector1 = *pSrcInput;
  341.         pSrcInput += 1;
  342.         vInVectorFirst = vInVector1;
  343.         
  344.         vInVector2 =     *pSrcInput;
  345.         pSrcInput += 1;
  346.         
  347.         vInVector3 =     *pSrcInput;
  348.         pSrcInput += 1;
  349.         
  350.         // set up multiplicand vectors using raw input vectors and permute instruction
  351.         vCand1 = vec_perm(vInVector1, vInVector1, vPermuter);
  352.         vCand2 = vec_perm(vInVector2, vInVector2, vPermuter);
  353.         vCand3 = vec_perm(vInVector3, vInVector3, vPermuter);
  354.         
  355.         // calculate pixel results by multiplying elements by the wavelet coefficients, 
  356.         // with additional add for appropriate rounding in divide
  357.         vResult1 = vec_msum(vMUL0, vCand1, (vector signed long)vecEndAdd);
  358.         vResult1 = vec_msum(vMUL1, vCand2, vResult1);
  359.         
  360.         vResult2 = vec_msum(vMUL2, vCand1, (vector signed long)vecEndAdd);
  361.         vResult2 = vec_msum(vMUL3, vCand2, vResult2);
  362.  
  363.         vResult3 = vec_msum(vMUL0, vCand2, (vector signed long)vecEndAdd);
  364.         vResult3 = vec_msum(vMUL1, vCand3, vResult3);
  365.         
  366.         vResult4 = vec_msum(vMUL2, vCand2, (vector signed long)vecEndAdd);
  367.         vResult4 = vec_msum(vMUL3, vCand3, vResult4);
  368.  
  369.         // do end shift to perform divide
  370.         vResult1 = vec_sra(vResult1,vecEndShift);
  371.         vResult2 = vec_sra(vResult2,vecEndShift);
  372.         vResult3 = vec_sra(vResult3,vecEndShift);
  373.         vResult4 = vec_sra(vResult4,vecEndShift);
  374.         
  375.         // pack results to 16 bits
  376.         vResult1 = (vector signed long)vec_pack(vResult1, vResult3);
  377.         vResult2 = (vector signed long)vec_pack(vResult2, vResult4);
  378.         
  379.         // store results
  380.         *pLoOutput++ = vResult1;
  381.         *pHiOutput++ = vResult2;
  382.         
  383.         vInVector1 = vInVector3;
  384.         
  385.         // loop through remaining pixels
  386.         for (vectorInIndex = 0; vectorInIndex < (numQuads-8)/4; vectorInIndex++) {
  387.         
  388.             vInVector2 = *pSrcInput;
  389.             pSrcInput += 1;
  390.  
  391.             vInVector3 = *pSrcInput;
  392.             pSrcInput += 1;
  393.                         
  394.             // set up multiplicand vectors using raw input vectors and permute instruction
  395.             vCand1 = vec_perm(vInVector1, vInVector1, vPermuter);
  396.             vCand2 = vec_perm(vInVector2, vInVector2, vPermuter);
  397.             vCand3 = vec_perm(vInVector3, vInVector3, vPermuter);
  398.             
  399.             // calculate pixel results by multiplying elements by the wavelet coefficients, 
  400.             // with additional add for appropriate rounding in divide
  401.             vResult1 = vec_msum(vMUL0, vCand1, (vector signed long)vecEndAdd);
  402.             vResult1 = vec_msum(vMUL1, vCand2, vResult1);
  403.             
  404.             vResult2 = vec_msum(vMUL2, vCand1, (vector signed long)vecEndAdd);
  405.             vResult2 = vec_msum(vMUL3, vCand2, vResult2);
  406.  
  407.             vResult3 = vec_msum(vMUL0, vCand2, (vector signed long)vecEndAdd);
  408.             vResult3 = vec_msum(vMUL1, vCand3, vResult3);
  409.             
  410.             vResult4 = vec_msum(vMUL2, vCand2, (vector signed long)vecEndAdd);
  411.             vResult4 = vec_msum(vMUL3, vCand3, vResult4);
  412.  
  413.             // do end shift to perform divide
  414.             vResult1 = vec_sra(vResult1,vecEndShift);
  415.             vResult2 = vec_sra(vResult2,vecEndShift);
  416.             vResult3 = vec_sra(vResult3,vecEndShift);
  417.             vResult4 = vec_sra(vResult4,vecEndShift);
  418.             
  419.             // pack results to 16 bits
  420.             vResult1 = (vector signed long)vec_pack(vResult1, vResult3);
  421.             vResult2 = (vector signed long)vec_pack(vResult2, vResult4);
  422.             
  423.             // store results
  424.             *pLoOutput++ = vResult1;
  425.             *pHiOutput++ = vResult2;
  426.                     
  427.             vInVector1 = vInVector3;
  428.         }
  429.         
  430.         vInVector2 = *pSrcInput;
  431.         pSrcInput += 1;
  432.             
  433.         vInVector3 = vInVectorFirst;
  434.         
  435.         // set up multiplicand vectors using raw input vectors and permute instruction
  436.         vCand1 = vec_perm(vInVector1, vInVector1, vPermuter);
  437.         vCand2 = vec_perm(vInVector2, vInVector2, vPermuter);
  438.         vCand3 = vec_perm(vInVector3, vInVector3, vPermuter);
  439.         
  440.         // calculate pixel results by multiplying elements by the wavelet coefficients, 
  441.         // with additional add for appropriate rounding in divide
  442.         vResult1 = vec_msum(vMUL0, vCand1, (vector signed long)vecEndAdd);
  443.         vResult1 = vec_msum(vMUL1, vCand2, vResult1);
  444.         
  445.         vResult2 = vec_msum(vMUL2, vCand1, (vector signed long)vecEndAdd);
  446.         vResult2 = vec_msum(vMUL3, vCand2, vResult2);
  447.  
  448.         vResult3 = vec_msum(vMUL0, vCand2, (vector signed long)vecEndAdd);
  449.         vResult3 = vec_msum(vMUL1, vCand3, vResult3);
  450.         
  451.         vResult4 = vec_msum(vMUL2, vCand2, (vector signed long)vecEndAdd);
  452.         vResult4 = vec_msum(vMUL3, vCand3, vResult4);
  453.  
  454.         // do end shift to perform divide
  455.         vResult1 = vec_sra(vResult1,vecEndShift);
  456.         vResult2 = vec_sra(vResult2,vecEndShift);
  457.         vResult3 = vec_sra(vResult3,vecEndShift);
  458.         vResult4 = vec_sra(vResult4,vecEndShift);
  459.         
  460.         // pack results to 16 bits
  461.         vResult1 = (vector signed long)vec_pack(vResult1, vResult3);
  462.         vResult2 = (vector signed long)vec_pack(vResult2, vResult4);
  463.         
  464.         // store results
  465.         *pLoOutput = vResult1;
  466.         *pHiOutput = vResult2;
  467.         
  468.     }    
  469. }
  470.  
  471. ////////////////////////////////////////////////////////////////////////////
  472. // vFWVT_4_Quad16_Int_ExpandFrom8 
  473. // 
  474. // performs a forward horizontal wavelet transform on 8 bit per channel
  475. // input data (RGBA interleaved), resulting in 16-bit output data.
  476. //
  477. // pSrc:                source pixels (8-bit interleaved RGBA channels)
  478. // pDest:                destination for transform data (16-bit interleaved RGBA channels)
  479. // numQuads:            horizontal pixel count
  480. // skipQuads:            number of quads between row starts
  481. // numRows:                number of rows on which to perform transform
  482. ////////////////////////////////////////////////////////////////////////////
  483. void vFWVT_4_Quad16_Int_ExpandFrom8(    vector unsigned char *pSrc,
  484.                             vector signed long *pDest,
  485.                             unsigned long numQuads,
  486.                             unsigned long skipQuads,
  487.                             unsigned long numRows)                
  488. {
  489.     long                    vectorInIndex;
  490.     long                    rowIndex;
  491.     
  492.     vector unsigned char        *pSrcInput;
  493.     vector signed long            *pLoOutput;
  494.     vector signed long            *pHiOutput;
  495.  
  496.     vector signed short            vMUL0    = (vector signed short)(H0, H1, H0, H1,H0, H1,H0, H1);
  497.     vector signed short            vMUL1    = (vector signed short)(H2, H3, H2, H3,H2, H3,H2, H3);
  498.     vector signed short            vMUL2    = (vector signed short)(H3, -H2,H3, -H2,H3, -H2,H3, -H2);
  499.     vector signed short            vMUL3    = (vector signed short)(H1, -H0,H1, -H0,H1, -H0,H1, -H0);
  500.  
  501.     vector signed short            vCand1;
  502.     vector signed short            vCand2;
  503.     vector signed short            vCand3;
  504.  
  505.     vector unsigned char        vPermuter = (vector unsigned char)(0x00, 0x01, 0x08, 0x09, 0x02, 0x03, 0x0a, 0x0b, 0x04, 0x05, 0x0c, 0x0d, 0x06, 0x07, 0x0e, 0x0f);
  506.     
  507.     vector unsigned long        vecEndShift = (vector unsigned long)(INT_WAVELET_SHIFT_AMOUNT);
  508.     vector signed long            vecEndAdd = (vector signed long)(1 << (INT_WAVELET_SHIFT_AMOUNT-1));
  509.     
  510.     vector unsigned char        vInVector1, vInVector2;
  511.     vector signed long            vResult1, vResult2, vResult3, vResult4;
  512.     vector unsigned char        vInVectorFirst;
  513.     
  514.     vector unsigned long        vZero = (vector unsigned long)(0);
  515.     
  516.     vector signed short            vExpanded1, vExpanded2, vExpanded3;
  517.     
  518.     
  519.     for (rowIndex = 0; rowIndex < numRows; rowIndex++) {
  520.  
  521.     
  522.         pSrcInput = pSrc+(rowIndex*(skipQuads/4));
  523.         pLoOutput = (vector signed long*)pDest+(rowIndex*(skipQuads/2));
  524.         pHiOutput = pLoOutput + (numQuads/4);
  525.     
  526.         // read the first two in, and save 1 for wraparound at end
  527.         vInVector1 = *pSrcInput;
  528.         pSrcInput += 1;
  529.         vInVectorFirst = vInVector1;
  530.         
  531.         vInVector2 =     *pSrcInput;
  532.         pSrcInput += 1;
  533.                 
  534.         // expand input vectors from 8 to 16 bits
  535.         vExpanded1 = (vector signed short)vec_mergeh((vector unsigned char)vZero, vInVector1);
  536.         vExpanded2 = (vector signed short)vec_mergel((vector unsigned char)vZero, vInVector1);
  537.         vExpanded3 = (vector signed short)vec_mergeh((vector unsigned char)vZero, vInVector2);
  538.                 
  539.         // set up multiplicand vectors using raw input vectors and permute instruction
  540.         vCand1 = vec_perm(vExpanded1, vExpanded1, vPermuter);
  541.         vCand2 = vec_perm(vExpanded2, vExpanded2, vPermuter);
  542.         vCand3 = vec_perm(vExpanded3, vExpanded3, vPermuter);
  543.         
  544.         // calculate pixel results by multiplying elements by the wavelet coefficients, 
  545.         // with additional add for appropriate rounding in divide
  546.         vResult1 = vec_msum(vMUL0, vCand1, (vector signed long)vecEndAdd);
  547.         vResult1 = vec_msum(vMUL1, vCand2, vResult1);
  548.         
  549.         vResult2 = vec_msum(vMUL2, vCand1, (vector signed long)vecEndAdd);
  550.         vResult2 = vec_msum(vMUL3, vCand2, vResult2);
  551.  
  552.         vResult3 = vec_msum(vMUL0, vCand2, (vector signed long)vecEndAdd);
  553.         vResult3 = vec_msum(vMUL1, vCand3, vResult3);
  554.         
  555.         vResult4 = vec_msum(vMUL2, vCand2, (vector signed long)vecEndAdd);
  556.         vResult4 = vec_msum(vMUL3, vCand3, vResult4);
  557.  
  558.         // do end shift to perform divide
  559.         vResult1 = vec_sra(vResult1,vecEndShift);
  560.         vResult2 = vec_sra(vResult2,vecEndShift);
  561.         vResult3 = vec_sra(vResult3,vecEndShift);
  562.         vResult4 = vec_sra(vResult4,vecEndShift);
  563.         
  564.         // pack results to 16 bits
  565.         vResult1 = (vector signed long)vec_pack(vResult1, vResult3);
  566.         vResult2 = (vector signed long)vec_pack(vResult2, vResult4);
  567.         
  568.         // store results
  569.         *pLoOutput++ = vResult1;
  570.         *pHiOutput++ = vResult2;
  571.  
  572.         vCand1 = vCand3;
  573.         vExpanded1 = (vector signed short)vec_mergel((vector unsigned char)vZero, vInVector2);
  574.         vCand2 = vec_perm(vExpanded1, vExpanded1, vPermuter);
  575.                                     
  576.         // loop through remaining pixels
  577.         for (vectorInIndex = 0; vectorInIndex < (numQuads/4)-2; vectorInIndex++) {
  578.             
  579.             vInVector1 = *pSrcInput++;
  580.             
  581.             vExpanded1 = (vector signed short)vec_mergeh((vector unsigned char)vZero, vInVector1);
  582.             vCand3 = vec_perm(vExpanded1, vExpanded1, vPermuter);
  583.             
  584.             // calculate pixel results by multiplying elements by the wavelet coefficients, 
  585.             // with additional add for appropriate rounding in divide
  586.             vResult1 = vec_msum(vMUL0, vCand1, (vector signed long)vecEndAdd);
  587.             vResult1 = vec_msum(vMUL1, vCand2, vResult1);
  588.             
  589.             vResult2 = vec_msum(vMUL2, vCand1, (vector signed long)vecEndAdd);
  590.             vResult2 = vec_msum(vMUL3, vCand2, vResult2);
  591.  
  592.             vResult3 = vec_msum(vMUL0, vCand2, (vector signed long)vecEndAdd);
  593.             vResult3 = vec_msum(vMUL1, vCand3, vResult3);
  594.             
  595.             vResult4 = vec_msum(vMUL2, vCand2, (vector signed long)vecEndAdd);
  596.             vResult4 = vec_msum(vMUL3, vCand3, vResult4);
  597.  
  598.             // do end shift to perform divide
  599.             vResult1 = vec_sra(vResult1,vecEndShift);
  600.             vResult2 = vec_sra(vResult2,vecEndShift);
  601.             vResult3 = vec_sra(vResult3,vecEndShift);
  602.             vResult4 = vec_sra(vResult4,vecEndShift);
  603.             
  604.             // pack results to 16 bits
  605.             vResult1 = (vector signed long)vec_pack(vResult1, vResult3);
  606.             vResult2 = (vector signed long)vec_pack(vResult2, vResult4);
  607.             
  608.             // store results
  609.             *pLoOutput++ = vResult1;
  610.             *pHiOutput++ = vResult2;
  611.  
  612.             vCand1 = vCand3;
  613.             vExpanded1 = (vector signed short)vec_mergel((vector unsigned char)vZero, vInVector1);
  614.             vCand2 = vec_perm(vExpanded1, vExpanded1, vPermuter);
  615.             
  616.         }
  617.         
  618.         vInVector1 = vInVectorFirst;
  619.         
  620.         // set up multiplicand vectors using raw input vectors and permute instruction
  621.         vExpanded1 = (vector signed short)vec_mergeh((vector unsigned char)vZero, vInVector1);
  622.         vCand3 = vec_perm(vExpanded1, vExpanded1, vPermuter);
  623.         
  624.         // calculate pixel results by multiplying elements by the wavelet coefficients, 
  625.         // with additional add for appropriate rounding in divide
  626.         vResult1 = vec_msum(vMUL0, vCand1, (vector signed long)vecEndAdd);
  627.         vResult1 = vec_msum(vMUL1, vCand2, vResult1);
  628.         
  629.         vResult2 = vec_msum(vMUL2, vCand1, (vector signed long)vecEndAdd);
  630.         vResult2 = vec_msum(vMUL3, vCand2, vResult2);
  631.  
  632.         vResult3 = vec_msum(vMUL0, vCand2, (vector signed long)vecEndAdd);
  633.         vResult3 = vec_msum(vMUL1, vCand3, vResult3);
  634.         
  635.         vResult4 = vec_msum(vMUL2, vCand2, (vector signed long)vecEndAdd);
  636.         vResult4 = vec_msum(vMUL3, vCand3, vResult4);
  637.  
  638.         // do end shift to perform divide
  639.         vResult1 = vec_sra(vResult1,vecEndShift);
  640.         vResult2 = vec_sra(vResult2,vecEndShift);
  641.         vResult3 = vec_sra(vResult3,vecEndShift);
  642.         vResult4 = vec_sra(vResult4,vecEndShift);
  643.         
  644.         // pack results to 16 bits
  645.         vResult1 = (vector signed long)vec_pack(vResult1, vResult3);
  646.         vResult2 = (vector signed long)vec_pack(vResult2, vResult4);
  647.         
  648.         // store results
  649.         *pLoOutput = vResult1;
  650.         *pHiOutput = vResult2;
  651.         
  652.     }    
  653. }
  654.  
  655. ////////////////////////////////////////////////////////////////////////////
  656. // vFWVT_4_Quad16_2DInt 
  657. // 
  658. // performs a two-dimensional forward wavelet on an image.  Performs the
  659. // number of transforms specified by depth.
  660. //
  661. // pSrc:                source pixels (8-bit interleaved RGBA channels)
  662. // pDst:                destination for transform data (16-bit interleaved RGBA channels)
  663. // pTemp:                temporary image store (16-bit interleaved RGBA channels, full image size)
  664. // x, y:                dimensions of image
  665. // rowQuads:            number of RGBA quads between row starts
  666. // depth:                depth of wavelet transforms to perform
  667. //
  668. //                        *NOTE* there is a limit of 3 for the wavelet depth
  669. //                        due to implementation limitations of the current
  670. //                         vector wavelet.  If a depth > 3 is used, then the
  671. //                        intermediate calculations will overflow the 16-bit
  672. //                        vector elements.
  673. //
  674. ////////////////////////////////////////////////////////////////////////////
  675.  
  676. void vFWVT_4_Quad16_2DInt(long *pSrc,
  677.                         long *pDst,
  678.                         long *pTemp,
  679.                         unsigned long x,
  680.                         unsigned long y,
  681.                         unsigned long rowQuads,
  682.                         unsigned long depth)
  683. {
  684.     unsigned long     depthIndex;
  685.     unsigned long    currentDepthHeight;
  686.     unsigned long    currentDepthWidth;
  687.         
  688.  
  689.     currentDepthHeight = y;
  690.     currentDepthWidth = x;
  691.  
  692.     // perform first forward horizontal transform, and
  693.     // simultaneously expand data from 8 to 16 bits.
  694.     vFWVT_4_Quad16_Int_ExpandFrom8(    (vector unsigned char*)pSrc,
  695.                     (vector signed long*)pTemp,
  696.                     currentDepthWidth,
  697.                     rowQuads,
  698.                     currentDepthHeight
  699.                     );                
  700.  
  701.     // perform first forward vertical transform
  702.     vFWVT_4_Quad16_Int_Vertical((vector signed long*)pTemp,
  703.                     (vector signed long*)pDst,
  704.                     currentDepthHeight,
  705.                     rowQuads,
  706.                     currentDepthWidth);                
  707.  
  708.  
  709.     // perform remaining depth transforms
  710.     for (depthIndex = 1; depthIndex < depth; depthIndex++) {
  711.         currentDepthHeight >>= 1;        
  712.         currentDepthWidth >>= 1;        
  713.     
  714.         // do horizontal transform
  715.         vFWVT_4_Quad16_Int(    (vector signed long*)pDst,
  716.                         (vector signed long*)pTemp,
  717.                         currentDepthWidth,
  718.                         rowQuads,
  719.                         currentDepthHeight
  720.                         );                
  721.  
  722.         // do vertical transform
  723.         vFWVT_4_Quad16_Int_Vertical((vector signed long*)pTemp,
  724.                         (vector signed long*)pDst,
  725.                         currentDepthHeight,
  726.                         rowQuads,
  727.                         currentDepthWidth);                
  728.  
  729.  
  730.     
  731.     }        
  732. }
  733.  
  734. #pragma mark -
  735.  
  736. #pragma mark I N V E R S E  W A V E L E T
  737.  
  738. ////////////////////////////////////////////////////////////////////////////
  739. // vIFWVT_4_Quad16_Int_Vertical 
  740. // 
  741. // performs an inverse vertical wavelet transform
  742. //
  743. // pSrc:                source pixels (16-bit interleaved RGBA channels)
  744. // pDest:                destination for transform data (16-bit interleaved RGBA channels)
  745. // numQuads:            vertical pixel count
  746. // skipQuadCount:        number of quads between row starts
  747. // columns:                number of columns on which to perform transform
  748. ////////////////////////////////////////////////////////////////////////////
  749.  
  750. void vIFWVT_4_Quad16_Int_Vertical(    vector signed long *pSrc,
  751.                             vector signed long *pDest,
  752.                             unsigned long numQuads,
  753.                             unsigned long skipQuadCount,
  754.                             unsigned long columns)                
  755. {
  756.     long                     length = (numQuads/2);
  757.     long                    vectorIndex;
  758.     long                    skipVectors = skipQuadCount / 2;
  759.     long                    columnIndex;
  760.     long                    columnCount = columns / 2;
  761.     
  762.     vector signed long        *pColumnOut;
  763.     vector signed short        *pSrcHi, *pSrcLo;
  764.     vector signed short        *pColStart;
  765.  
  766.     vector signed short            vMUL0        = (vector signed short)(H1, H3, H1, H3, H1, H3, H1, H3);
  767.     vector signed short            vMUL1        = (vector signed short)(-H2, -H0, -H2, -H0, -H2, -H0, -H2, -H0);
  768.     vector signed short            vMUL2        = (vector signed short)(H0, H2, H0, H2, H0, H2, H0, H2);
  769.     vector signed short            vMUL3        = (vector signed short)(H3, H1, H3, H1, H3, H1, H3, H1);
  770.  
  771.     vector signed short            vCand1;
  772.     vector signed short            vCand2;
  773.     vector signed short            vCand3;
  774.     vector signed short            vCand4;
  775.     
  776.     vector unsigned char        vPermuter1 = (vector unsigned char)(0x00, 0x01, 0x10, 0x11, 0x02, 0x03, 0x12, 0x13, 0x04, 0x05, 0x14, 0x15, 0x06, 0x07, 0x16, 0x17);
  777.     vector unsigned char        vPermuter2 = (vector unsigned char)(0x08, 0x09, 0x18, 0x19, 0x0a, 0x0b, 0x1a, 0x1b, 0x0c, 0x0d, 0x1c, 0x1d, 0x0e, 0x0f, 0x1e, 0x1f);
  778.  
  779.     vector unsigned long        vecEndShift = (vector unsigned long)(INVERSE_WAVELET_SHIFT_AMOUNT);
  780.     vector signed long            vecEndAdd = (vector signed long)(1 << (INVERSE_WAVELET_SHIFT_AMOUNT-1));
  781.  
  782.     vector signed short            vInVector1, vInVector2, vInVector3, vInVector4;
  783.     vector signed long            vResult1, vResult2, vResult3, vResult4;
  784.     
  785.     vector unsigned long        vecOnes = (vector unsigned long)(3);
  786.     
  787.     for (columnIndex = 0; columnIndex < columnCount; columnIndex++) {
  788.  
  789.         pColumnOut = pDest + columnIndex;
  790.         pColStart = (vector signed short*)pSrc+columnIndex;
  791.         pSrcLo = pColStart;
  792.         pSrcHi = pSrcLo + (skipVectors*numQuads)/2;
  793.         
  794.         // read in input vectors    
  795.         vInVector1 = *pSrcLo;
  796.         vInVector2 = *(pSrcHi-skipVectors);
  797.         vInVector3 = *pSrcHi;
  798.         vInVector4 = *(pSrcLo+((numQuads-1)*(skipVectors)));
  799.  
  800.         pSrcHi+=skipVectors;
  801.         pSrcLo+=skipVectors;
  802.  
  803.         // set up multiplicand vectors using raw input vectors and permute instruction
  804.         vCand1 = vec_perm(vInVector1, vInVector2, vPermuter1);
  805.         vCand2 = vec_perm(vInVector3, vInVector4, vPermuter1);
  806.  
  807.         // calculate pixel results by multiplying elements by the wavelet coefficients, 
  808.         // with additional add for appropriate rounding in divide
  809.         vResult1 = vec_msum(vMUL0, vCand1, vecEndAdd);    
  810.         vResult1 = vec_msum(vMUL1, vCand2, (vector signed long)vResult1);    
  811.  
  812.         vResult2 = vec_msum(vMUL2, vCand1, vecEndAdd);    
  813.         vResult2 = vec_msum(vMUL3, vCand2, (vector signed long)vResult2);    
  814.  
  815.         // do end shift to perform divide
  816.         vResult1 = vec_sra(vResult1,vecEndShift);
  817.         vResult2 = vec_sra(vResult2,vecEndShift);
  818.         
  819.         // set up multiplicand vectors using raw input vectors and permute instruction
  820.         vCand3 = vec_perm(vInVector1, vInVector2, vPermuter2);
  821.         vCand4 = vec_perm(vInVector3, vInVector4, vPermuter2);
  822.  
  823.         // calculate pixel results by multiplying elements by the wavelet coefficients, 
  824.         // with additional add for appropriate rounding in divide
  825.         vResult3 = vec_msum(vMUL0, vCand3, vecEndAdd);    
  826.         vResult3 = vec_msum(vMUL1, vCand4, (vector signed long)vResult3);    
  827.  
  828.         vResult4 = vec_msum(vMUL2, vCand3, vecEndAdd);    
  829.         vResult4 = vec_msum(vMUL3, vCand4, (vector signed long)vResult4);    
  830.  
  831.         // do end shift to perform divide
  832.         vResult3 = vec_sra(vResult3,vecEndShift);
  833.         vResult4 = vec_sra(vResult4,vecEndShift);
  834.  
  835.         // pack results to 16 bits and store results
  836.         *pColumnOut = (vector signed long)vec_pack(vResult2, vResult4);
  837.         pColumnOut += skipVectors;
  838.  
  839.         *pColumnOut = (vector signed long)vec_pack(vResult1, vResult3);
  840.         pColumnOut += skipVectors;
  841.                 
  842.         for (vectorIndex = 0; vectorIndex < length-1; vectorIndex++) {
  843.  
  844.             // read in input vectors    
  845.             vInVector2 = *pSrcLo;        
  846.             vInVector4 = *pSrcHi;        
  847.  
  848.             pSrcHi+=skipVectors;
  849.             pSrcLo+=skipVectors;
  850.  
  851.             // set up multiplicand vectors using raw input vectors and permute instruction
  852.             vCand1 = vec_perm(vInVector2, vInVector1, vPermuter1);
  853.             vCand2 = vec_perm(vInVector4, vInVector3, vPermuter1);
  854.  
  855.             // calculate pixel results by multiplying elements by the wavelet coefficients, 
  856.             // with additional add for appropriate rounding in divide
  857.             vResult1 = vec_msum(vMUL2, vCand1, vecEndAdd);    
  858.             vResult1 = vec_msum(vMUL3, vCand2, (vector signed long)vResult1);    
  859.  
  860.             vResult2 = vec_msum(vMUL0, vCand1, vecEndAdd);    
  861.             vResult2 = vec_msum(vMUL1, vCand2, (vector signed long)vResult2);    
  862.  
  863.             // do end shift to perform divide
  864.             vResult1 = vec_sra(vResult1,vecEndShift);
  865.             vResult2 = vec_sra(vResult2,vecEndShift);
  866.             
  867.             // set up multiplicand vectors using raw input vectors and permute instruction
  868.             vCand3 = vec_perm(vInVector2, vInVector1, vPermuter2);
  869.             vCand4 = vec_perm(vInVector4, vInVector3, vPermuter2);
  870.  
  871.             // calculate pixel results by multiplying elements by the wavelet coefficients, 
  872.             // with additional add for appropriate rounding in divide
  873.             vResult3 = vec_msum(vMUL2, vCand3, vecEndAdd);    
  874.             vResult3 = vec_msum(vMUL3, vCand4, (vector signed long)vResult3);    
  875.  
  876.             vResult4 = vec_msum(vMUL0, vCand3, vecEndAdd);    
  877.             vResult4 = vec_msum(vMUL1, vCand4, (vector signed long)vResult4);    
  878.  
  879.             // do end shift to perform divide
  880.             vResult3 = vec_sra(vResult3,vecEndShift);
  881.             vResult4 = vec_sra(vResult4,vecEndShift);
  882.  
  883.             // pack results to 16 bits and store results
  884.             *pColumnOut = (vector signed long)vec_pack(vResult1, vResult3);
  885.             pColumnOut += skipVectors;
  886.             
  887.             *pColumnOut = (vector signed long)vec_pack(vResult2, vResult4);
  888.             pColumnOut += skipVectors;
  889.  
  890.             vInVector1 = vInVector2;
  891.             vInVector3 = vInVector4;            
  892.         }
  893.  
  894.     }    
  895. }
  896.  
  897.  
  898. ////////////////////////////////////////////////////////////////////////////
  899. // vIFWVT_4_Quad16_Int_PackTo8 
  900. // 
  901. // performs an inverse horizontal wavelet transform, and packs final
  902. // data from 16 bits to 8 bits per channel.
  903. //
  904. // pSrc:                source pixels (16-bit interleaved RGBA channels)
  905. // pDest:                destination for transform data (8-bit interleaved RGBA channels)
  906. // numQuads:            horizontal pixel count
  907. // skipQuads:            number of quads between row starts
  908. // numRows:                number of rows on which to perform transform
  909. ////////////////////////////////////////////////////////////////////////////
  910.  
  911. static void vIFWVT_4_Quad16_Int_PackTo8(    vector signed long *pSrc,
  912.                             vector signed long *pDest,
  913.                             unsigned long numQuads,
  914.                             unsigned long skipQuads,
  915.                             unsigned long numRows)                
  916. {
  917.     long                     length = (numQuads/2);
  918.     long                    vectorIndex;
  919.     long                    rowIndex;
  920.     
  921.     vector signed long        *pRowDest;
  922.     vector signed short        *pSrcHi, *pSrcLo;
  923.     vector signed short        *pRowStart;
  924.     
  925.  
  926.     vector signed short            vMUL0        = (vector signed short)(H3, H1, H3, H1, H3, H1, H3, H1);
  927.     vector signed short            vMUL1        = (vector signed short)(-H0, -H2, -H0, -H2, -H0, -H2, -H0, -H2);
  928.     vector signed short            vMUL2        = (vector signed short)(H2, H0, H2, H0, H2, H0, H2, H0);
  929.     vector signed short            vMUL3        = (vector signed short)(H1, H3, H1, H3, H1, H3, H1, H3);
  930.  
  931.     vector signed short            vCand1;
  932.     vector signed short            vCand2;
  933.     vector signed short            vCand3;
  934.     vector signed short            vCand4;
  935.     
  936.     vector unsigned char        vPermuter1_first =    (vector unsigned char)(0x08, 0x09, 0x10, 0x11, 0x0a, 0x0b, 0x12, 0x13, 0x0c, 0x0d, 0x14, 0x15, 0x0e, 0x0f, 0x16, 0x17);
  937.     vector unsigned char        vPermuter2_first = (vector unsigned char)(0x10, 0x11, 0x18, 0x19, 0x12, 0x13, 0x1a, 0x1b, 0x14, 0x15, 0x1c, 0x1d, 0x16, 0x17, 0x1e, 0x1f);    
  938.  
  939.     vector unsigned long        vecEndShift = (vector unsigned long)(INVERSE_WAVELET_SHIFT_AMOUNT);
  940.     vector signed long            vecEndAdd = (vector signed long)(1 << (INVERSE_WAVELET_SHIFT_AMOUNT-1));
  941.  
  942.     vector signed short            vInVector1, vInVector2, vInVector3, vInVector4;
  943.     vector signed long            vResult1, vResult2, vResult3, vResult4;
  944.     
  945.     vector unsigned long        vZero = (vector unsigned long)(0);
  946.  
  947.     vector unsigned long        vecOnes = (vector unsigned long)(3);
  948.     
  949.     vector signed short            prepackResultHi, prepackResultLo;
  950.     
  951.     vector signed short            vMax = (vector signed short)(0xff);
  952.     
  953.         
  954.     for (rowIndex = 0; rowIndex < numRows; rowIndex++) {
  955.  
  956.         pRowDest = (vector signed long*)pDest + (rowIndex*(skipQuads/4));
  957.         pRowStart = (vector signed short*)pSrc + (rowIndex*(skipQuads/2));
  958.         pSrcLo = pRowStart;
  959.         pSrcHi = pSrcLo + (numQuads/4);
  960.                 
  961.         // read in input vectors    
  962.         vInVector1 = *pSrcLo;
  963.         vInVector2 = *(pSrcHi-1);
  964.         vInVector3 = *pSrcHi;
  965.         vInVector4 = *(pSrcLo+((numQuads-2)/2));
  966.  
  967.         // set up multiplicand vectors using raw input vectors and permute instruction
  968.         vCand1 = vec_perm(vInVector2, vInVector1, vPermuter1_first);
  969.         vCand2 = vec_perm(vInVector4, vInVector3, vPermuter1_first);
  970.  
  971.         // calculate pixel results by multiplying elements by the wavelet coefficients, 
  972.         // with additional add for appropriate rounding in divide
  973.         vResult1 = vec_msum(vMUL0, vCand1, vecEndAdd);    
  974.         vResult1 = vec_msum(vMUL1, vCand2, (vector signed long)vResult1);    
  975.  
  976.         vResult2 = vec_msum(vMUL2, vCand1, vecEndAdd);    
  977.         vResult2 = vec_msum(vMUL3, vCand2, (vector signed long)vResult2);    
  978.  
  979.         // do end shift to perform divide
  980.         vResult1 = vec_sra(vResult1,vecEndShift);
  981.         vResult2 = vec_sra(vResult2,vecEndShift);
  982.  
  983.         // pack to 16, and  ensure max/min of 0 and 255 before pack to 8 bits
  984.         prepackResultHi = (vector signed short)vec_pack(vResult2, vResult1);
  985.         
  986.         prepackResultHi = vec_max((vector signed short)vZero, prepackResultHi);
  987.         prepackResultHi = vec_min(vMax, prepackResultHi);
  988.         
  989.         //////////////////////////////////
  990.         
  991.         // set up multiplicand vectors using raw input vectors and permute instruction
  992.         vCand3 = vec_perm(vInVector2, vInVector1, vPermuter2_first);
  993.         vCand4 = vec_perm(vInVector4, vInVector3, vPermuter2_first);
  994.  
  995.         // calculate pixel results by multiplying elements by the wavelet coefficients, 
  996.         // with additional add for appropriate rounding in divide
  997.         vResult3 = vec_msum(vMUL0, vCand3, vecEndAdd);    
  998.         vResult3 = vec_msum(vMUL1, vCand4, (vector signed long)vResult3);    
  999.  
  1000.         vResult4 = vec_msum(vMUL2, vCand3, vecEndAdd);    
  1001.         vResult4 = vec_msum(vMUL3, vCand4, (vector signed long)vResult4);    
  1002.  
  1003.         // do end shift to perform divide
  1004.         vResult3 = vec_sra(vResult3,vecEndShift);
  1005.         vResult4 = vec_sra(vResult4,vecEndShift);
  1006.  
  1007.         // pack to 16, and  ensure max/min of 0 and 255 before pack to 8 bits
  1008.         prepackResultLo = (vector signed short)vec_pack(vResult4, vResult3);
  1009.  
  1010.         prepackResultLo = vec_max((vector signed short)vZero, prepackResultLo);
  1011.         prepackResultLo = vec_min(vMax, prepackResultLo);
  1012.  
  1013.         // pack to 8 bits and store result
  1014.         *pRowDest++ = (vector signed long)vec_pack(prepackResultHi, prepackResultLo);
  1015.  
  1016.         ++pSrcLo;
  1017.         ++pSrcHi;
  1018.         
  1019.         for (vectorIndex = 0; vectorIndex < (length/2)-1; vectorIndex++) {
  1020.             // read in input vectors    
  1021.             vInVector2 = *pSrcLo++;
  1022.             vInVector4 = *pSrcHi++;
  1023.                 
  1024.             // set up multiplicand vectors using raw input vectors and permute instruction
  1025.             vCand1 = vec_perm(vInVector1, vInVector2, vPermuter1_first);
  1026.             vCand2 = vec_perm(vInVector3, vInVector4, vPermuter1_first);
  1027.  
  1028.             // calculate pixel results by multiplying elements by the wavelet coefficients, 
  1029.             // with additional add for appropriate rounding in divide
  1030.             vResult1 = vec_msum(vMUL0, vCand1, vecEndAdd);    
  1031.             vResult1 = vec_msum(vMUL1, vCand2, (vector signed long)vResult1);    
  1032.  
  1033.             vResult2 = vec_msum(vMUL2, vCand1, vecEndAdd);    
  1034.             vResult2 = vec_msum(vMUL3, vCand2, (vector signed long)vResult2);    
  1035.  
  1036.             // do end shift to perform divide
  1037.             vResult1 = vec_sra(vResult1,vecEndShift);
  1038.             vResult2 = vec_sra(vResult2,vecEndShift);
  1039.  
  1040.             // pack to 16, and  ensure max/min of 0 and 255 before pack to 8 bits
  1041.             prepackResultHi = (vector signed short)vec_pack(vResult2, vResult1);
  1042.             
  1043.             prepackResultHi = vec_max((vector signed short)vZero, prepackResultHi);
  1044.             prepackResultHi = vec_min(vMax, prepackResultHi);
  1045.             
  1046.             //////////////////////////////////
  1047.             
  1048.             // set up multiplicand vectors using raw input vectors and permute instruction
  1049.             vCand3 = vec_perm(vInVector1, vInVector2, vPermuter2_first);
  1050.             vCand4 = vec_perm(vInVector3, vInVector4, vPermuter2_first);
  1051.  
  1052.             // calculate pixel results by multiplying elements by the wavelet coefficients, 
  1053.             // with additional add for appropriate rounding in divide
  1054.             vResult3 = vec_msum(vMUL0, vCand3, vecEndAdd);    
  1055.             vResult3 = vec_msum(vMUL1, vCand4, (vector signed long)vResult3);    
  1056.  
  1057.             vResult4 = vec_msum(vMUL2, vCand3, vecEndAdd);    
  1058.             vResult4 = vec_msum(vMUL3, vCand4, (vector signed long)vResult4);    
  1059.  
  1060.             vResult3 = vec_sra(vResult3,vecEndShift);
  1061.             vResult4 = vec_sra(vResult4,vecEndShift);
  1062.  
  1063.             // pack to 16, and  ensure max/min of 0 and 255 before pack to 8 bits
  1064.             prepackResultLo = (vector signed short)vec_pack(vResult4, vResult3);
  1065.  
  1066.             prepackResultLo = vec_max((vector signed short)vZero, prepackResultLo);
  1067.             prepackResultLo = vec_min(vMax, prepackResultLo);
  1068.  
  1069.             // pack to 8 bits and store result
  1070.             
  1071.             *pRowDest++ = (vector signed long)vec_pack(prepackResultHi, prepackResultLo);
  1072.  
  1073.             vInVector1 = vInVector2;
  1074.             vInVector3 = vInVector4;
  1075.             
  1076.         }
  1077.  
  1078.     }    
  1079. }
  1080.  
  1081.  
  1082.  
  1083.  
  1084. ////////////////////////////////////////////////////////////////////////////
  1085. // vIFWVT_4_Quad16_Int 
  1086. // 
  1087. // performs an inverse horizontal wavelet transform
  1088. //
  1089. // pSrc:                source pixels (16-bit interleaved RGBA channels)
  1090. // pDest:                destination for transform data (16-bit interleaved RGBA channels)
  1091. // numQuads:            horizontal pixel count
  1092. // skipQuads:            number of quads between row starts
  1093. // numRows:                number of rows on which to perform transform
  1094. ////////////////////////////////////////////////////////////////////////////
  1095.  
  1096. void vIFWVT_4_Quad16_Int(    vector signed long *pSrc,
  1097.                             vector signed long *pDest,
  1098.                             unsigned long numQuads,
  1099.                             unsigned long skipQuads,
  1100.                             unsigned long numRows)                
  1101. {
  1102.     long                     length = (numQuads/2);
  1103.     long                    vectorIndex;
  1104.     long                    rowIndex;
  1105.     
  1106.     vector signed long        *pRowDest;
  1107.     vector signed short        *pSrcHi, *pSrcLo;
  1108.     vector signed short        *pRowStart;
  1109.     
  1110.  
  1111.     vector signed short            vMUL0        = (vector signed short)(H3, H1, H3, H1, H3, H1, H3, H1);
  1112.     vector signed short            vMUL1        = (vector signed short)(-H0, -H2, -H0, -H2, -H0, -H2, -H0, -H2);
  1113.     vector signed short            vMUL2        = (vector signed short)(H2, H0, H2, H0, H2, H0, H2, H0);
  1114.     vector signed short            vMUL3        = (vector signed short)(H1, H3, H1, H3, H1, H3, H1, H3);
  1115.  
  1116.     vector signed short            vCand1;
  1117.     vector signed short            vCand2;
  1118.     vector signed short            vCand3;
  1119.     vector signed short            vCand4;
  1120.     
  1121.     vector unsigned char        vPermuter1_first =    (vector unsigned char)(0x08, 0x09, 0x10, 0x11, 0x0a, 0x0b, 0x12, 0x13, 0x0c, 0x0d, 0x14, 0x15, 0x0e, 0x0f, 0x16, 0x17);
  1122.     vector unsigned char        vPermuter2_first = (vector unsigned char)(0x10, 0x11, 0x18, 0x19, 0x12, 0x13, 0x1a, 0x1b, 0x14, 0x15, 0x1c, 0x1d, 0x16, 0x17, 0x1e, 0x1f);    
  1123.  
  1124.     vector unsigned long        vecEndShift = (vector unsigned long)(INVERSE_WAVELET_SHIFT_AMOUNT);
  1125.     vector signed long            vecEndAdd = (vector signed long)(1 << (INVERSE_WAVELET_SHIFT_AMOUNT-1));
  1126.  
  1127.     vector signed short            vInVector1, vInVector2, vInVector3, vInVector4;
  1128.     vector signed long            vResult1, vResult2, vResult3, vResult4;
  1129.     
  1130.     vector unsigned long        vecOnes = (vector unsigned long)(3);
  1131.         
  1132.     for (rowIndex = 0; rowIndex < numRows; rowIndex++) {
  1133.         
  1134.         pRowDest = (vector signed long*)pDest + (rowIndex*(skipQuads/2));;
  1135.         pRowStart = (vector signed short*)pSrc + (rowIndex*(skipQuads/2));
  1136.         pSrcLo = pRowStart;
  1137.         pSrcHi = pSrcLo + (numQuads/4);
  1138.                 
  1139.         // read in input vectors    
  1140.         vInVector1 = *pSrcLo;
  1141.         vInVector2 = *(pSrcHi-1);
  1142.         vInVector3 = *pSrcHi;
  1143.         vInVector4 = *(pSrcLo+((numQuads-2)/2));
  1144.  
  1145.         vCand1 = vec_perm(vInVector2, vInVector1, vPermuter1_first);
  1146.         vCand2 = vec_perm(vInVector4, vInVector3, vPermuter1_first);
  1147.  
  1148.         vResult1 = vec_msum(vMUL0, vCand1, vecEndAdd);    
  1149.         vResult1 = vec_msum(vMUL1, vCand2, (vector signed long)vResult1);    
  1150.  
  1151.         vResult2 = vec_msum(vMUL2, vCand1, vecEndAdd);    
  1152.         vResult2 = vec_msum(vMUL3, vCand2, (vector signed long)vResult2);    
  1153.  
  1154.         vResult1 = vec_sra(vResult1,vecEndShift);
  1155.         vResult2 = vec_sra(vResult2,vecEndShift);
  1156.  
  1157.         *pRowDest++ = (vector signed long)vec_pack(vResult2, vResult1);
  1158.                 
  1159.         vCand3 = vec_perm(vInVector2, vInVector1, vPermuter2_first);
  1160.         vCand4 = vec_perm(vInVector4, vInVector3, vPermuter2_first);
  1161.  
  1162.         // calculate pixel results by multiplying elements by the wavelet coefficients, 
  1163.         // with additional add for appropriate rounding in divide
  1164.         vResult3 = vec_msum(vMUL0, vCand3, vecEndAdd);    
  1165.         vResult3 = vec_msum(vMUL1, vCand4, (vector signed long)vResult3);    
  1166.  
  1167.         vResult4 = vec_msum(vMUL2, vCand3, vecEndAdd);    
  1168.         vResult4 = vec_msum(vMUL3, vCand4, (vector signed long)vResult4);    
  1169.  
  1170.         // do end shift to perform divide
  1171.         vResult3 = vec_sra(vResult3,vecEndShift);
  1172.         vResult4 = vec_sra(vResult4,vecEndShift);
  1173.  
  1174.         *pRowDest++ = (vector signed long)vec_pack(vResult4, vResult3);
  1175.  
  1176.         ++pSrcLo;
  1177.         ++pSrcHi;
  1178.         
  1179.         for (vectorIndex = 0; vectorIndex < (length/2)-1; vectorIndex++) {
  1180.             // read in input vectors    
  1181.             vInVector2 = *pSrcLo++;
  1182.             vInVector4 = *pSrcHi++;
  1183.                 
  1184.             // set up multiplicand vectors using raw input vectors and permute instruction
  1185.             vCand1 = vec_perm(vInVector1, vInVector2, vPermuter1_first);
  1186.             vCand2 = vec_perm(vInVector3, vInVector4, vPermuter1_first);
  1187.  
  1188.             vResult1 = vec_msum(vMUL0, vCand1, vecEndAdd);    
  1189.             vResult1 = vec_msum(vMUL1, vCand2, (vector signed long)vResult1);    
  1190.  
  1191.             vResult2 = vec_msum(vMUL2, vCand1, vecEndAdd);    
  1192.             vResult2 = vec_msum(vMUL3, vCand2, (vector signed long)vResult2);    
  1193.  
  1194.             vResult1 = vec_sra(vResult1,vecEndShift);
  1195.             vResult2 = vec_sra(vResult2,vecEndShift);
  1196.  
  1197.             // pack result to 16 bits and store
  1198.             *pRowDest++ = (vector signed long)vec_pack(vResult2, vResult1);
  1199.             
  1200.             
  1201.             // set up multiplicand vectors using raw input vectors and permute instruction
  1202.             vCand3 = vec_perm(vInVector1, vInVector2, vPermuter2_first);
  1203.             vCand4 = vec_perm(vInVector3, vInVector4, vPermuter2_first);
  1204.  
  1205.             // calculate pixel results by multiplying elements by the wavelet coefficients, 
  1206.             // with additional add for appropriate rounding in divide
  1207.             vResult3 = vec_msum(vMUL0, vCand3, vecEndAdd);    
  1208.             vResult3 = vec_msum(vMUL1, vCand4, (vector signed long)vResult3);    
  1209.  
  1210.             vResult4 = vec_msum(vMUL2, vCand3, vecEndAdd);    
  1211.             vResult4 = vec_msum(vMUL3, vCand4, (vector signed long)vResult4);    
  1212.  
  1213.             // do end shift to perform divide
  1214.             vResult3 = vec_sra(vResult3,vecEndShift);
  1215.             vResult4 = vec_sra(vResult4,vecEndShift);
  1216.  
  1217.             // pack result to 16 bits and store
  1218.             *pRowDest++ = (vector signed long)vec_pack(vResult4, vResult3);
  1219.  
  1220.             ///////////////////////////////////
  1221.             
  1222.             vInVector1 = vInVector2;
  1223.             vInVector3 = vInVector4;
  1224.             
  1225.         }
  1226.  
  1227.     }    
  1228. }
  1229.  
  1230.  
  1231. ////////////////////////////////////////////////////////////////////////////
  1232. // vIFWVT_4_Quad16_2DInt 
  1233. // 
  1234. // performs a two-dimensional inverse wavelet on an image.  Performs the
  1235. // number of transforms specified by depth.
  1236. //
  1237. // pSrc:                source pixels (8-bit interleaved RGBA channels)
  1238. // pDst:                destination for transform data (16-bit interleaved RGBA channels)
  1239. // pTemp:                temporary image store (16-bit interleaved RGBA channels, full image size)
  1240. // x, y:                dimensions of image
  1241. // rowQuads:            number of RGBA quads between row starts
  1242. // depth:                depth of wavelet transforms to perform
  1243. //
  1244. //                        *NOTE* there is a limit of 3 for the wavelet depth
  1245. //                        due to implementation limitations of the current
  1246. //                         vector wavelet.  If a depth > 3 is used, then the
  1247. //                        intermediate calculations will overflow the 16-bit
  1248. //                        vector elements.
  1249. //
  1250. //                        *NOTE* transform may destroy source data, as it
  1251. //                         uses it as temp storage for an intermediate transform
  1252. ////////////////////////////////////////////////////////////////////////////
  1253.  
  1254.  
  1255. void vIFWVT_4_Quad16_2DInt(long *pSrc,
  1256.                         long *pDst,
  1257.                         long *pTemp,
  1258.                         unsigned long x,
  1259.                         unsigned long y,
  1260.                         unsigned long rowQuads,
  1261.                         unsigned long depth)                
  1262. {
  1263.     unsigned long     depthIndex;
  1264.     unsigned long    currentDepthHeight;
  1265.     unsigned long    currentDepthWidth;
  1266.     
  1267.     
  1268.     currentDepthHeight = y >> (depth);
  1269.     currentDepthWidth =  x >> (depth);
  1270.  
  1271.     // if depth is 1, perform transform directly to dest
  1272.     if (depth == 1) {
  1273.         currentDepthHeight     <<= 1;
  1274.         currentDepthWidth     <<= 1;
  1275.  
  1276.         // to vertical from source to temp
  1277.         vIFWVT_4_Quad16_Int_Vertical((vector signed long*)pSrc,
  1278.                         (vector signed long*)pTemp,
  1279.                         currentDepthHeight,
  1280.                         rowQuads,
  1281.                         currentDepthWidth);            
  1282.  
  1283.         // to horizontal from temp to dest, pack to 8 bits
  1284.         vIFWVT_4_Quad16_Int_PackTo8((vector signed long*)pTemp,
  1285.                         (vector signed long*)pDst,
  1286.                         currentDepthWidth,
  1287.                         rowQuads,
  1288.                         currentDepthHeight
  1289.                         );            
  1290.  
  1291.     
  1292.     
  1293.     } else if (depth) {
  1294.  
  1295.         // loop through all but last depth
  1296.         for (depthIndex = 0; depthIndex < depth-1; depthIndex++) {
  1297.             currentDepthHeight     <<= 1;
  1298.             currentDepthWidth     <<= 1;
  1299.             
  1300.         // do vertical transform from source to temp
  1301.         vIFWVT_4_Quad16_Int_Vertical((vector signed long*)pSrc,
  1302.                         (vector signed long*)pTemp,
  1303.                         currentDepthHeight,
  1304.                         rowQuads,
  1305.                         currentDepthWidth);            
  1306.  
  1307.  
  1308.         // do horizontal transform from temp to src
  1309.         vIFWVT_4_Quad16_Int((vector signed long*)pTemp,
  1310.                         (vector signed long*)pSrc,
  1311.                         currentDepthWidth,
  1312.                         rowQuads,
  1313.                         currentDepthHeight
  1314.                         );            
  1315.         
  1316.  
  1317.  
  1318.         }
  1319.         
  1320.         currentDepthHeight     <<= 1;
  1321.         currentDepthWidth     <<= 1;
  1322.  
  1323.         // to vertical from source to temp
  1324.         vIFWVT_4_Quad16_Int_Vertical((vector signed long*)pSrc,
  1325.                         (vector signed long*)pTemp,
  1326.                         currentDepthHeight,
  1327.                         rowQuads,
  1328.                         currentDepthWidth);            
  1329.  
  1330.  
  1331.         // to horizontal from temp to dest, pack to 8 bits
  1332.         vIFWVT_4_Quad16_Int_PackTo8((vector signed long*)pTemp,
  1333.                         (vector signed long*)pDst,
  1334.                         currentDepthWidth,
  1335.                         rowQuads,
  1336.                         currentDepthHeight
  1337.                         );            
  1338.  
  1339.     
  1340.     }
  1341.  
  1342. }
  1343.  
  1344.